
namespace gen {

	///////////////////////////////////////////////////////////////////////////
    //
    //  limit class implementation
    //
    ///////////////////////////////////////////////////////////////////////////

	template<typename OldInfoT, typename NewInfoT >
	inline const limit_base<OldInfoT,NewInfoT> 
	limit_base<OldInfoT,NewInfoT>::operator+(typename limit_base<OldInfoT,NewInfoT>::diff_t offset_)
	{
		return limit_base(base_cur, offset+offset_);
	}

	template<typename OldInfoT, typename NewInfoT >
	inline const limit_base<OldInfoT,NewInfoT>
	limit_base<OldInfoT,NewInfoT>::operator-(typename limit_base<OldInfoT,NewInfoT>::diff_t offset_)
	{
		return limit_base(base_cur, offset-offset_);
	}

	template<typename OldInfoT, typename NewInfoT >
	inline const limit_base<OldInfoT,NewInfoT> 
	operator+(typename limit_base<OldInfoT,NewInfoT>::diff_t offset_, const limit_base<OldInfoT,NewInfoT> & l)
	{
		return limit_base<OldInfoT,NewInfoT>(l.base_cur, l.offset+offset_);
	}

	template<typename OldInfoT, typename NewInfoT >
	typename limit_base<OldInfoT,NewInfoT>::new_iterator_t 
	limit_base<OldInfoT,NewInfoT>::get_limit(typename limit_base<OldInfoT,NewInfoT>::old_iterator_t const& iteParent) const
	{
		typename NewInfoT::range_t cont(*iteParent);
		typename NewInfoT::iterator_t iteChild;
		if (base_cur == beg) {
			iteChild = cont.begin();
		} else {
			iteChild = cont.end();
		}
		return iteChild+offset;
	}

	///////////////////////////////////////////////////////////////////////////
    //
    //  limits class implementation
    //
    ///////////////////////////////////////////////////////////////////////////

	template<typename OldInfoT, typename NewInfoT>
	inline limits<OldInfoT, NewInfoT> 
	operator,(const limit_base<OldInfoT,NewInfoT> & b1, const limit_base<OldInfoT,NewInfoT> & b2)
	{
		return limits<OldInfoT, NewInfoT>(b1, b2);
	}	

	template<typename OldInfoT, typename NewInfoT>
	inline limits<OldInfoT, NewInfoT>
	operator,(const limit_base<OldInfoT,NewInfoT> & b1, int offset)
	{
		limit_base<OldInfoT,NewInfoT> b2(limit_base<OldInfoT,NewInfoT>::beg, offset);
		return limits<OldInfoT, NewInfoT>(b1, b2);
	}

	template<typename OldInfoT, typename NewInfoT>
	inline limits<OldInfoT, NewInfoT>
	operator,(int offset, const limit_base<OldInfoT,NewInfoT> & b2)
	{
		limit_base<OldInfoT,NewInfoT> b1(limit_base<OldInfoT,NewInfoT>::beg, offset);
		return limits<OldInfoT, NewInfoT>(b1, b2);
	}

	template<typename OldInfoT, typename NewInfoT >
	typename limits<OldInfoT,NewInfoT>::new_iterator_t 
	limits<OldInfoT,NewInfoT>::first(typename limits<OldInfoT,NewInfoT>::old_iterator_t const& iteParent) const
	{
		return l_first.get_limit(iteParent);
	}

	template<typename OldInfoT, typename NewInfoT >
	typename limits<OldInfoT,NewInfoT>::new_iterator_t 
	limits<OldInfoT,NewInfoT>::last(typename limits<OldInfoT,NewInfoT>::old_iterator_t const& iteParent) const
	{
		return l_last.get_limit(iteParent);
	}

	///////////////////////////////////////////////////////////////////////////
    //
    //  loop class implementation
    //
    ///////////////////////////////////////////////////////////////////////////

	template <typename S, typename LimitsT>
	template <typename InfoT>
	void
	loop<S,LimitsT>::generate(InfoT & info_) const
    {
		typedef typename LimitsT::iterator_t			iterator_t;
		typedef typename LimitsT::info_t::char_t		char_t;
		typedef typename LimitsT::info_t::vector_t		vector_t;
		const int pos = LimitsT::info_t::pos;

		for (iterator_t i = l.first(info_.first());
			 i != l.last(info_.first());
			 ++i)
        {
			generator_info<char_t,vector_t,pos> info(i, l.last(info_.first()));
            this->subject().generate(info);
			info_.append(info.str());
        }

    }

    template <typename DerivedT>
	template <class OldInfoT, class NewInfoT>
	inline loop< DerivedT, limits<OldInfoT,NewInfoT> >
	generator<DerivedT>::operator[](limits<OldInfoT,NewInfoT> const& l) const
    {
        return loop<DerivedT, limits<OldInfoT,NewInfoT> >(derived(), l);
    }

}
